package com.godyao.mall.pms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.godyao.mall.pms.dao.AttrAttrgroupRelationDao;
import com.godyao.mall.pms.dao.AttrDao;
import com.godyao.mall.pms.entity.AttrAttrgroupRelationEntity;
import com.godyao.mall.pms.entity.AttrEntity;
import com.godyao.mall.pms.service.AttrAttrgroupRelationService;
import com.godyao.mall.pms.service.AttrService;
import com.godyao.mall.pms.vo.request.AttrGroupRequestVo;
import com.godyao.mall.pms.vo.response.AttrGroupResponseVo;
import com.godyao.mall.pms.vo.response.AttrResponseVo;
import lombok.RequiredArgsConstructor;
import org.checkerframework.checker.units.qual.A;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.godyao.mall.core.utils.PageUtils;
import com.godyao.mall.core.utils.Query;

import com.godyao.mall.pms.dao.AttrGroupDao;
import com.godyao.mall.pms.entity.AttrGroupEntity;
import com.godyao.mall.pms.service.AttrGroupService;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;


@Service("attrGroupService")
@RequiredArgsConstructor
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {
    private final AttrAttrgroupRelationService attrAttrgroupRelationService;

    private final AttrDao attrDao;

    private final AttrGroupDao attrGroupDao;

    private final AttrAttrgroupRelationDao relationDao;

    /**
     * 获取当前分组没有关联的所有属性
     * @param params
     * @param attrgroupId
     * @return
     */
    @Override
    public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrgroupId) {
        // 1 当前分组只能关联自己所属的分类里面的所有属性
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId);
        Long catelogId = attrGroupEntity.getCatelogId();
        // 2 当前分组只能关联别的分组没有引用的属性
        // 2.1 当前分类下的其他分组
        List<AttrGroupEntity> group = attrGroupDao.selectList(new QueryWrapper<AttrGroupEntity>().eq("catelog_id", catelogId));
        List<Long> collect = group.stream().map((item) -> item.getAttrGroupId()).collect(Collectors.toList());
        // 2.2 这些分组关联的属性
        List<AttrAttrgroupRelationEntity> groupId = relationDao.selectList(new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", collect));
        List<Long> attrIds = groupId.stream().map((item) -> item.getAttrId()).collect(Collectors.toList());
        // 2.3 从当前分类下的所有属性移除这些属性
        QueryWrapper<AttrEntity> wrapper = new QueryWrapper<AttrEntity>().eq("catelog_id", catelogId).eq("attr_type",1);
        if (attrIds != null && attrIds.size() > 0) {
            wrapper.notIn("attr_id",attrIds);
        }
        String key = (String) params.get("key");
        if (!StringUtils.isEmpty(key)) {
            wrapper.and((w)->{
                w.eq("attr_id",key).or().like("attr_name",key);

            });
        }
        IPage<AttrEntity> page = attrDao.selectPage(new Query<AttrEntity>().getPage(params), wrapper);
        PageUtils pageUtils = new PageUtils(page);

        return pageUtils;
    }

    @Override
    public void saveBatch(List<AttrGroupRequestVo> requestVos) {
        final List<AttrAttrgroupRelationEntity> collect = requestVos.stream()
                .map(attrGroupRequestVo -> {
                    final AttrAttrgroupRelationEntity attrGroupEntity = new AttrAttrgroupRelationEntity();
                    BeanUtil.copyProperties(attrGroupRequestVo, attrGroupEntity);
                    return attrGroupEntity;
                }).collect(Collectors.toList());
        attrAttrgroupRelationService.saveBatch(collect);
    }

    @Override
    public List<AttrGroupResponseVo> getAttrGroupByCateId(Long catelogId) {

        final List<AttrGroupEntity> attrGroupEntities = attrGroupDao.selectList(
                        new LambdaQueryWrapper<AttrGroupEntity>()
                                .eq(AttrGroupEntity::getCatelogId, catelogId))
                .stream()
                .collect(Collectors.toList());
        final List<AttrGroupResponseVo> result = attrGroupEntities.parallelStream()
                .map(attrGroupEntity -> {
                    final AttrGroupResponseVo attrGroupResponseVo = new AttrGroupResponseVo();
                    final Long attrGroupId = attrGroupEntity.getAttrGroupId();

                    final List<Long> attrIds = relationDao.selectList(
                            new LambdaQueryWrapper<AttrAttrgroupRelationEntity>()
                            .eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupId))
                            .stream()
                            .map(AttrAttrgroupRelationEntity::getAttrId)
                            .collect(Collectors.toList());
                    final List<AttrEntity> attrEntities = attrDao.selectBatchIds(attrIds);
                    BeanUtil.copyProperties(attrGroupEntity, attrGroupResponseVo);
                    attrGroupResponseVo.setAttrs(attrEntities);
                    return attrGroupResponseVo;
                }).collect(Collectors.toList());
        return result;

    }

    @Override
    public void removeRelations(AttrGroupRequestVo[] attrGroupIds) {
        Long[] attrIds = new Long[attrGroupIds.length];
        for (int i = 0; i < attrGroupIds.length; i++) {
            final AttrGroupRequestVo attrGroupId = attrGroupIds[i];
            attrIds[i] = attrGroupId.getAttrId();
        }
        if (attrIds.length > 0) {
            attrAttrgroupRelationService.lambdaUpdate()
                    .in(AttrAttrgroupRelationEntity::getAttrId, attrIds)
                    .remove();
        }

    }

    @Override
    public List<AttrEntity> listAttrByGroup(Long attrGroupId) {
        final List<Long> attrIds = attrAttrgroupRelationService.lambdaQuery()
                .select(AttrAttrgroupRelationEntity::getAttrId)
                .eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrGroupId)
                .list()
                .stream()
                .map(AttrAttrgroupRelationEntity::getAttrId)
                .collect(Collectors.toList());
        List<AttrEntity> attrEntities = new ArrayList<>();
        if (!CollectionUtils.isEmpty(attrIds)) {
            attrEntities = attrDao.selectBatchIds(attrIds);
        }

        return attrEntities;
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params, Long catlogId) {
        if (catlogId.equals(0L)) {
            return queryPage(params);
        }
        final String key = (String) params.get("key");
        final LambdaQueryChainWrapper<AttrGroupEntity> queryChainWrapper = this.lambdaQuery()
                .eq(AttrGroupEntity::getCatelogId, catlogId)
                .and(StrUtil.isNotBlank(key),
                        q -> q.like(AttrGroupEntity::getAttrGroupName, key)
                                .or().eq(AttrGroupEntity::getAttrGroupId, key)
                );
        final IPage<AttrGroupEntity> page = queryChainWrapper.page(new Query<AttrGroupEntity>().getPage(params));
        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                new QueryWrapper<AttrGroupEntity>()
        );

        return new PageUtils(page);
    }

}
